package com.geh.learn.hutool;

import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.google.common.base.Charsets;
import com.google.common.io.BaseEncoding;

import javax.crypto.Cipher;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class EncryptRsaTest {

    public static void main(String[] args) throws Exception {

        // 获得对象 KeyPairGenerator 参数 RSA 1024个字节
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(1024);
        // 通过对象 KeyPairGenerator 获取对象KeyPair
        KeyPair keyPair = keyPairGen.generateKeyPair();
        // 通过对象 KeyPair 获取RSA公私钥对象RSAPublicKey RSAPrivateKey
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        // 把得到的密钥base64一下
        String publicKeyBase64 = BaseEncoding.base64().encode(publicKey.getEncoded());
        String privateKeyBase64 = BaseEncoding.base64().encode(privateKey.getEncoded());

        System.out.println("publicKeyBase64 = " + publicKeyBase64);
        System.out.println("privateKeyBase64 = " + privateKeyBase64);

        String original = "Hello World!";
        System.out.println("original = " + original);


        RSA rsa = new RSA("RSA/ECB/PKCS1Padding", privateKeyBase64, publicKeyBase64);
        String hutoolRsa = rsa.encryptBase64(original, KeyType.PublicKey);
        System.out.println("hutoolRsa public " + hutoolRsa);

        String hutoolRsaPrivate =  rsa.encryptBase64(original, KeyType.PrivateKey);
        System.out.println("hutoolRsa private " + hutoolRsaPrivate);

        System.out.println("hutoolRsa decrypt " + rsa.decryptStr(hutoolRsa, KeyType.PrivateKey));


        // java默认"RSA"="RSA/ECB/PKCS1Padding"  加密处理
        X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(BaseEncoding.base64().decode(publicKeyBase64));
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(pubKeySpec);
        Cipher cipherEncrypt = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipherEncrypt.init(Cipher.ENCRYPT_MODE, pubKey);
        String encryptedContent = BaseEncoding.base64().encode(cipherEncrypt.doFinal(original.getBytes(Charsets.UTF_8)));
        System.out.println("encryptedContent = " + encryptedContent);

        // 解密处理
        PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(BaseEncoding.base64().decode(privateKeyBase64));
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(priKeySpec);
        Cipher cipherDecrypt = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipherDecrypt.init(Cipher.DECRYPT_MODE, priKey);
        String decryptedContent = new String(cipherDecrypt.doFinal(BaseEncoding.base64().decode(encryptedContent)), Charsets.UTF_8);
        System.out.println("decryptedContent = " + decryptedContent);

        // 验证用Hutool加密的字符串，用我们自己写的功能代码，也是可以解密的。
        String decryptedContentHutool = new String(cipherDecrypt.doFinal(BaseEncoding.base64().decode(hutoolRsa)), Charsets.UTF_8);
        System.out.println("decryptedContentHutool = " + decryptedContentHutool);

        String hutoolDecryptLocal = rsa.decryptStr(encryptedContent, KeyType.PrivateKey);
        System.out.println("hutoolDecryptLocal " + hutoolDecryptLocal);

    }

}
